package com.jiangdong.craft.entity;

import org.springframework.util.CollectionUtils;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * t_craft
 * @author 
 */
public class Craft implements Serializable {

    private static final long serialVersionUID = 1L;

    private Integer id;

    private String name;

    private String describe;

    private String label;

    private Date createTime;

    //节点集合
    private List<Procedure> procedures;


    /*
    * 判断是否存在闭环的方法 循环得到一个起点 判断是否有节点指向或被指向  否则跳出本次循环  拿到此节点的指向节点。。。。
    * */

    public boolean closeLoop() {

        for (Procedure procedure : procedures) {
            if (CollectionUtils.isEmpty(procedure.getFrontNodes()) || CollectionUtils.isEmpty(procedure.getPostNodes())){
                continue;
            }
            //起点指向的节点
            List<Procedure> procedureList = findProcedureByProcedure(procedure,this.procedures);
            if (closedLoop(procedure.getId(),procedureList)) {
                return true;
            }
        }
        return false;
    }


    //判断节点是否存在闭环 procedureList当前遍历点的指向节点或子指向节点集合集合
    private boolean closedLoop(Integer nowId, List<Procedure> procedureList) {

        for (Procedure procedure : procedureList) {
            if (!CollectionUtils.isEmpty(procedure.getFrontNodes())){
                for (Integer id : procedure.getFrontNodes()){
                    if (id.equals(nowId)){
                        return true;
                    }
                }
            }
        }

        for (Procedure procedure : procedureList){
            //判断递归是否继续  若没有指向节点的list则不递归
            if (!CollectionUtils.isEmpty(procedure.getFrontNodes())){
                List<Procedure> procedures = findProcedureByProcedure(procedure,this.procedures);
                closedLoop(nowId,procedures);
            }
        }

        return false;
    }

    //查询指向节点
    private List<Procedure> findProcedureByProcedure(Procedure procedure, List<Procedure> procedures) {
        List<Procedure> res = new ArrayList<>();
        for (Procedure procedure1 : procedures) {
            for (Integer id : procedure.getFrontNodes()) {
                if (procedure1.getId().equals(id)) {
                    res.add(procedure1);
                }
            }
        }

        return res;
    }

    //查询指向节点
    private Procedure findProcedureById(Integer id, List<Procedure> procedures) {
        for (Procedure procedure1 : procedures) {
            if (id.equals(procedure1.getId())) {
                return procedure1;
            }
        }

        return null;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Craft)) return false;
        Craft craft = (Craft) o;
        return Objects.equals(getId(), craft.getId()) &&
                Objects.equals(getName(), craft.getName()) &&
                Objects.equals(getDescribe(), craft.getDescribe()) &&
                Objects.equals(getLabel(), craft.getLabel()) &&
                Objects.equals(getCreateTime(), craft.getCreateTime()) &&
                Objects.equals(getProcedures(), craft.getProcedures());
    }

    @Override
    public int hashCode() {
        return Objects.hash(getId(), getName(), getDescribe(), getLabel(), getCreateTime(), getProcedures());
    }

    @Override
    public String toString() {
        return "Craft{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", describe='" + describe + '\'' +
                ", label='" + label + '\'' +
                ", createTime=" + createTime +
                ", procedures=" + procedures +
                '}';
    }

    public static long getSerialVersionUID() {
        return serialVersionUID;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescribe() {
        return describe;
    }

    public void setDescribe(String describe) {
        this.describe = describe;
    }

    public String getLabel() {
        return label;
    }

    public void setLabel(String label) {
        this.label = label;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public List<Procedure> getProcedures() {
        return procedures;
    }

    public void setProcedures(List<Procedure> procedures) {
        this.procedures = procedures;
    }
}